package com.pet.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pet.dto.Result;
import com.pet.dto.UserLoginDTO;
import com.pet.dto.UserRegisterDTO;
import com.pet.entity.UserDO;
import com.pet.enums.StatusCodeEnum;
import com.pet.mapper.UserMapper;
import com.pet.service.LoginService;
import com.pet.utils.EncryptSha256Util;
import com.pet.utils.JwtUtil;
import com.pet.utils.UserContextUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Objects;

@Service
public class LoginServiceImpl extends ServiceImpl<UserMapper, UserDO> implements LoginService {

    @Resource
    private UserMapper userMapper;

    @Override
    @Transactional
    public Result register(UserRegisterDTO dto) {
        if (StringUtils.isEmpty(dto.getUsername())) {
            return Result.result(StatusCodeEnum.PARAM_EMPTY.getCode(), "用户名不能为空");
        }
        if (StringUtils.isEmpty(dto.getPassword())) {
            return Result.result(StatusCodeEnum.PARAM_EMPTY.getCode(), "密码不能为空");
        }
        UserDO userDO = new UserDO();
        BeanUtil.copyProperties(dto, userDO);
        Result result = registerCheck(dto);
        if (result.getCode() != Result.SUCCESS) {
            return result;
        }
        userDO.setCreatedAt(DateUtil.date());
        userDO.setPassword(EncryptSha256Util.getSha256Str(dto.getPassword()));
        userMapper.insert(userDO);
        return Result.success("注册成功");
    }

    @Override
    public Result registerCheck(UserRegisterDTO dto) {
        if (StringUtils.isEmpty(dto.getUsername())) {
            return Result.success();
        }
        LambdaQueryWrapper<UserDO> queryWrapper = Wrappers.<UserDO>lambdaQuery()
                .eq(UserDO::getUsername, dto.getUsername());
        Long count = userMapper.selectCount(queryWrapper);
        if (count > 0) {
            return Result.error("用户名重复");
        }
        return Result.success();
    }

    @Override
    public Result login(UserLoginDTO dto) {
        LambdaQueryWrapper<UserDO> queryWrapper = Wrappers.<UserDO>lambdaQuery()
                .eq(UserDO::getUsername, dto.getUsername());
        UserDO userDO = userMapper.selectOne(queryWrapper);
        if (Objects.isNull(userDO)) {
            return Result.error("该用户未注册");
        }
        if (!StringUtils.equals(EncryptSha256Util.getSha256Str(dto.getPassword()), userDO.getPassword())) {
            return Result.error("密码错误");
        }
        //生成令牌
        String token = JwtUtil.createToken(userDO.getUsername());
        userDO.setToken(token);
        LambdaUpdateWrapper<UserDO> updateWrapper = Wrappers.<UserDO>lambdaUpdate()
                .eq(UserDO::getUsername, dto.getUsername())
                .set(UserDO::getToken, token);
        userMapper.update(userDO, updateWrapper);
        return Result.success(userDO);
    }

    @Override
    public Result logout(UserLoginDTO dto) {
        UserDO currentUser = UserContextUtil.getCurrentUser();
        LambdaUpdateWrapper<UserDO> updateWrapper = Wrappers.<UserDO>lambdaUpdate()
                .eq(UserDO::getUsername, currentUser.getUsername())
                .set(UserDO::getToken, null);
        this.update(updateWrapper);
        return Result.success("退出登录成功");
    }

    @Override
    public Result updatePassword(UserLoginDTO dto) {
        UserDO currentUser = UserContextUtil.getCurrentUser();
        LambdaUpdateWrapper<UserDO> updateWrapper = Wrappers.<UserDO>lambdaUpdate()
                .eq(UserDO::getUsername, currentUser.getUsername())
                .set(UserDO::getPassword, EncryptSha256Util.getSha256Str(dto.getPassword()))
                .set(UserDO::getToken, null);
        this.update(updateWrapper);
        return Result.success("密码修改成功");
    }

    @Override
    public Result updateInfo(UserRegisterDTO dto) {
        UserDO currentUser = UserContextUtil.getCurrentUser();
        LambdaUpdateWrapper<UserDO> updateWrapper = Wrappers.<UserDO>lambdaUpdate()
                .eq(UserDO::getUsername, currentUser.getUsername())
                .set(UserDO::getPhone, dto.getPhone())
                .set(UserDO::getEmail, dto.getEmail());
        this.update(updateWrapper);
        currentUser.setPhone(dto.getPhone());
        currentUser.setEmail(dto.getEmail());
        return Result.success(currentUser);
    }
}